import { render, h, shallowReactive } from 'vue'
import type { CreateMessageProps, MessageContext } from './types'
import MessageConstructor from './Message.vue'
import useZIndex from './../../hooks/useZIndex'

// 实例id
let seed = 1
// message实例数组
const instances: MessageContext[] = shallowReactive([])

// 注册message实例
export const createMessage = (props: CreateMessageProps) => {
    const id = `message_${seed++}`
    const { nextZindex } = useZIndex()
    const container = document.createElement('div')
    // 组件销毁 -- 卸载
    const onDestroy = () => {
        // 移除数组中实例
        const index = instances.findIndex((instance) => instance.id === id)
        if (index == -1) return
        instances.splice(index, 1)
        render(null, container)
    }
    // 手动触发组件销毁---修改props.visible为false
    const manualDestroy = () => {
        const instance = instances.find(instance => instance.id === id)
        if (instance) {
          instance.vm.exposed!.visible.value = false
        }
    }
    // 扩展props
    const newProps = {
        ...props,
        id,
        zIndex: nextZindex(),
        onDestory: onDestroy,
    }
    
    // 创建组件实例vnode--此时会执行getLastInstanceBottomOffset函数，但instances里面还未添加当前instance，会导致不获取的bottomOffset一直为0（一直找不到）
    // 解决方法：使用shallowReactive声明instances数组，进行响应式处理，reactive也行，但不需要深度响应式，只需要响应数组的增加与删除即可
    const vnode = h(MessageConstructor, newProps)
    render(vnode, container)
    //非空断言操作符
    document.body.appendChild(container.firstElementChild!)
    
    const instance = {
        id,
        vnode,
        // 组件实例本身(外面是一堆包装) -- 只有render函数执行后才有vm实例
        vm: vnode.component!,
        props: newProps,
        destory: manualDestroy
    }
    instances.push(instance)
    
    return instance
}

// 获取最后一个实例
export const getLastInstance = () => {
    return instances.at(-1)
}

// 获取最后一个实例的BottomOffset
export const getLastInstanceBottomOffset = (id: string) => {
    const index = instances.findIndex((instance) => instance.id === id)
    if (index <= 0) return 0
    // 当前传入id的实例的前一个实例
    const preInstance = instances[index - 1]
    // 返回前一个实例的bottomOffset
    return preInstance.vm.exposed!.bottomOffset.value
}

// 关闭所有实例
export const closeAll = () => {
    instances.forEach(instance => {
        instance.destory()
    })
}